'''
https://openstd.samr.gov.cn/bzgk/std/newGbInfo?hcno=D103A7D75B9D162F43A8BD9FC9FC35F4
国旗制法说明 http://chinaflag.org.cn/?list_16/369.html
（一九四九年九月二十八日中国人民政治协商会议第一届全体会议主席团公布）
 国旗的形状、颜色两面相同，旗上五星两面相对。为便利计，本件仅以旗杆在左之一面为说之标准。对于旗杆在右之一 面，凡本件所称左均应改右，所称右均应改左。
（一） 旗面为红色，长方形，其长与高为三与二之比，旗面左上方缀黄色五角星五颗。一星较大，其外接圆直径为旗高十分之三，居左；四星较小，其外接圆直径为旗高十分之一，环拱于大星之右。旗杆套为白色。
（二） 五星之位置与画法如下：
甲 、为便于确定五星之位置，先将旗面对分为四个相等的长方形，将左上方之长方形上下划为十等分，左右划为十五等分。
乙 、大五角星的中心点，在该长方形上五下五、左五右十之处。
其画法为：以此点为圆心，以三等分为半径作一圆。在此圆周上，定出五个等距离的点，其一点须位于圆之正上方。然后将此五点中各相隔的两点相联，使各成一直线。此五直线所构成之外轮廓线，即为所需之大五角星。五角星之一个角尖正向上方。
丙 、四颗小五角星的中心点，第一点在该长方形上二下八、左十右五之处，第二点在上四下六、左十二右三之处，第三点在上七下三、左十二右三之处，第四点在上九下一、左十右五之处。其画法为：以以上四点为圆心，各以一等分为半径，分别作四个圆。在每个圆上各定出五个等距离的点，其中均须各有一点位于大五角星中心点与以上四个圆心的各联结线上。然后用构成大五角星的同样方法，构成小五角星。此四颗小五角星均各有一个角尖正对大五角星的中心点
（三） 国旗之通用尺度定为如下五种，各界酌情选用：
甲、长288公分，高192公分。
乙、长240公分，高160公分。
丙、长192公分，高128公分。
丁、长144公分，高96公分。
戊、长96公分，高64公分。
'''
import turtle
import math

### 函数定义 开始 ###

# 计算两点的角度
def calculate_angle(x1, y1, x2, y2):
    """计算点(x1, y1)到点(x2, y2)的角度（其连线与x轴的夹角）"""
    # 计算水平和垂直差异
    dx = x2 - x1; dy = y2 - y1

    # x 相等时直接返回 90
    if dx == 0: return 90

    # 使用arctan函数计算角度，将弧度转换为角度
    return math.degrees(math.atan2(dy, dx))

# 两点连线
def draw_line(pen: turtle.Turtle, x1, y1, x2, y2):
    '''将 点(x1, y1) 与 点(x2, y2) 用线连接'''
    pen.teleport(x1, y1)
    pen.pendown()
    pen.goto(x2, y2)

# 画圆
def draw_circle(pen: turtle.Turtle, x = 0, y = 0, radius = 50, color = "yellow"):
    '''以 （x, y）为圆心，以 radius 为半径画圆'''
    pen.color(color)
    pen.setheading(0) # 归正方向
    pen.teleport(x, y - radius)  # 圆心偏下一个半径
    pen.pendown()
    pen.circle(radius)

# 画五角星
def draw_star(pen: turtle.Turtle, x = 0, y = 0, radius = 50, heading_angle = 90, color = "yellow"):
    '''
    Draw a filled five-pointed star at a specified position, size, orientation, and color using a turtle pen

    :param pen: The turtle pen used to draw the star
    :type pen: turtle.Turtle
    :param x: X-coordinate of the star's center
    :param y: Y-coordinate of the star's center
    :param radius: Distance from center to star tip
    :param heading_angle: Initial orientation angle of the star
    :param color: Fill color of the star
    '''
    pen.color(color)
    # pen.pencolor(color)
    # pen.fillcolor(color)

    # 调整方向
    pen.setheading(heading_angle) 

    # 根据半径计算边长
    side = radius * math.sin(math.radians(72)) / (1 + math.sin(math.radians(18)))

    pen.penup() # 提起笔
    pen.goto(x, y) # 到圆心
    pen.forward(radius) # 到圆边
    pen.right(180 - 18) # 掉头后便转18度
    # pen.pendown() # 不放下笔时不画边框，但会填充

    ## 开始画五角星
    pen.begin_fill() # 开始填充
    for _ in range(5):
        pen.forward(side)
        pen.left(72)
        pen.forward(side)
        pen.right(144)
    pen.end_fill() # 结束填充
    ## 结束画五角星

    pen.setheading(0) # 调整回方向

### 函数定义 结束 ###

### 参数预备 开始 ###
# 设置国旗的尺寸（标准比例3:2）。
flag_width = 288 * 3  # 甲、长288公分，高192公分。
# 旗高用宽计算，不直接使用# 192 * 3
flag_height = flag_width * 2 / 3

star_radius_b = flag_height * 3 / 10 / 2
star_radius_l = flag_height * 1 / 10 / 2

print("宽", flag_width, "高", flag_height)
print("主星大小", star_radius_b, "副星大小", star_radius_l)

# 设置画布
screen = turtle.getscreen()
screen.title("中华人民共和国国旗")
screen.setup(flag_width + 100, flag_height + 100)
#screen.bgcolor("red")

pen = turtle.getpen()
pen.shape("turtle")
pen.speed(0) # 速度放到最快

# 绘制红色背景
pen.teleport(-flag_width/2, flag_height/2)
pen.color("red")
pen.begin_fill()
for _ in range(2):
    pen.forward(flag_width)
    pen.right(90)
    pen.forward(flag_height)
    pen.right(90)
pen.end_fill()
pen.color("black")

# 左上·左右15等分
parts_width = 15
step_width = flag_width / 2 / parts_width
print("step_width:", step_width)

# 左上·上下10等分
parts_height = 10
step_height = flag_height / 2 / parts_height
print("step_height:", step_height)

# 大五角星的中心点，在该长方形上五下五、左五右十之处。
# 四颗小五角星的中心点:
#   第一点在该长方形上二下八、左十右五之处，
#   第二点在上四下六、左十二右三之处，
#   第三点在上七下三、左十二右三之处，
#   第四点在上九下一、左十右五之处
centers = [(0 - step_width * 10, step_height * 5, star_radius_b), 
           (0 - step_width * 5, step_height * 8, star_radius_l), 
           (0 - step_width * 3, step_height * 6, star_radius_l), 
           (0 - step_width * 3, step_height * 3, star_radius_l), 
           (0 - step_width * 5, step_height * 1, star_radius_l)]

### 参数预备 结束 ###

### 画参考线 开始 ###

# 画x轴
pen.teleport(0 - flag_width / 2, 0)
pen.setheading(0)
pen.forward(flag_width)

# 画y轴
pen.teleport(0, 0 - flag_height / 2)
pen.setheading(90)
pen.forward(flag_height)

# 画 左右15等分线
pen.setheading(90)
for step in range(1, parts_width):
    #pen.penup()
    pen.teleport(0 - step_width * step, 0)
    pen.pendown()
    pen.forward(flag_height / 2)

# 画 左上·上下10等分线
pen.setheading(0)
for step in range(1, parts_height):
    #pen.penup()
    pen.teleport(0 - flag_width / 2, step_height * step)
    pen.pendown()
    pen.forward(flag_width / 2)

### 画参考线 结束 ###

### 绘制开始 ###

# 大星中心点与半径
x0, y0, r0 = centers[0] 
# 画图
for x, y, r in centers:
    # 画外接圆
    draw_circle(pen, x, y, r)
    # 连线到大圆
    draw_line(pen, x, y, x0, y0)
    # 定点方向
    heading = calculate_angle(x, y, x0, y0)
    # 画五角星
    draw_star(pen, x, y, r, heading)

### 绘制结束 ###

# 收笔
pen.hideturtle()
# 持续显示
screen.mainloop()
